package com.sunwayhorizo.health.platform.security.dao.impl;

import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.Query;

import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.common.DateUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.platform.base.BaseManager;
import com.sunwayhorizo.health.platform.common.PlatformConstant;
import com.sunwayhorizo.health.platform.common.SecurityQueryConditions;
import com.sunwayhorizo.health.platform.security.dao.SecurityAccountDao;
import com.sunwayhorizo.health.platform.security.persistent.SecurityAccount;
import com.sunwayhorizo.health.platform.util.JPAUtil;

@Stateless
@Name("SecurityAccountDao")
public class SecurityAccountImpl extends BaseManager implements SecurityAccountDao{

	@Override
	public SecurityAccount newSecurityAccount(SecurityAccount account) {
		super.save(account);
		return account;
	}

	@Override
	public void deleteSecurityAccount(List<String> list) {
		super.delete(SecurityAccount.class,list);
	}

	@Override
	public SecurityAccount updateSecurityAccount(SecurityAccount account) {
		super.update(account);
		return account;
	}
	
	@Override
	public void updateSecurityAccountPassword(SecurityAccount account) {
		super.entityManager2.createQuery("update SecurityAccount sa set sa.password = :password").setParameter("password", account.getPassword());
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<SecurityAccount> findSecurityAccountList() {
		return super.entityManager2.createQuery("select sa from SecurityAccount sa where sa.deleted is null or sa.deleted !=1 ").getResultList();
	}

	@Override
	public SecurityAccount findSecurityAccountDetailById(String id) {
		return super.find(SecurityAccount.class, id);
	}

	@Override
	public SecurityAccount findSecurityAccountDetailByName(String accountName) {
		return (SecurityAccount)super.entityManager2.createQuery("select sa from SecurityAccount sa where sa.accountName = :accountName and (sa.deleted is null or sa.deleted !=1)").setParameter("accountName", accountName).getSingleResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<SecurityAccount> findSecurityAccountListByRoleId(String roleId) {
		return super.entityManager2.createQuery("select sar.account from SecurityAccountRole sar where sar.role.roleId = :roleId").setParameter("roleId", roleId).getResultList();
	}

	@SuppressWarnings("unchecked")
    @Override
    public List<SecurityAccount> findSecurityAccountListNotHasRole(String roleId) {
	    String sql=" select sa from SecurityAccount sa where (sa.deleted is null or sa.deleted !=1) and ( not exists( select sar.accountRoleId from SecurityAccountRole sar where sa = sar.account and sar.role.roleId is not null ) ";
	    if( StrUtil.isNotEmpty(roleId)){
	        sql +=" or exists( select sar2.accountRoleId from SecurityAccountRole sar2 where sa = sar2.account and sar2.role.roleId = :roleId ) ";
	    }
	    sql+=" )";
	    Query query  = super.entityManager2.createQuery(sql);
	    if( StrUtil.isNotEmpty(roleId)){
	        query.setParameter("roleId", roleId);
	    }
	    return query.getResultList();
    }

	@Override
	public List<SecurityAccount> findSecurityAccountListByAccount(SecurityAccount account) {
		return findSecurityAccountListByAccount(PlatformConstant.ALL_POS,PlatformConstant.ALL_POS,account);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<SecurityAccount> findSecurityAccountListByAccount(int startPosition,int pageSize, SecurityAccount account) {
		StringBuffer jpql = new StringBuffer("select sa from SecurityAccount sa where 1=1 and (sa.deleted is null or sa.deleted !=1) ");
		if( account!= null ){
		    if(StrUtil.isNotEmpty(account.getOrgId())){
		        jpql.append(" and sa.orgId = :orgId ");
		    }
		    if(StrUtil.isNotEmpty(account.getDeptId())){
                jpql.append(" and sa.deptId = :deptId ");
            }
		    if(StrUtil.isNotEmpty(account.getEmpId())){
                jpql.append(" and sa.empId = :empId ");
            }
			if(StrUtil.isNotEmpty(account.getAccountName())){
				jpql.append(" and locate(lower(:accountName),lower(sa.accountName) )>0 ");
			}
			if(account.getStartTime()!= null){
				jpql.append(" and sa.startTime >= :startTime ");
			}
			if(account.getEndTime()!= null){
				jpql.append(" and sa.endTime <= :endTime ");
			}
			if(StrUtil.isNotEmpty(account.getState())){
				jpql.append(" and sa.state = :state ");
			}
			if(ListUtil.isNotEmpty(account.getAccountRoles())){
			    jpql.append(" and exists( ").append(
			    	        "  select asr.accountRoleId from SecurityAccountRole asr where asr.account.accountId = sa.accountId "
			    ).append("     and asr.role.roleId =:roleId ")
			    .append(" )");
			}
			Query q = super.entityManager2.createQuery(jpql.toString());
			
			if(StrUtil.isNotEmpty(account.getOrgId())){
			    q.setParameter("orgId", account.getOrgId());
            }
            if(StrUtil.isNotEmpty(account.getDeptId())){
                q.setParameter("deptId", account.getDeptId());
            }
            if(StrUtil.isNotEmpty(account.getEmpId())){
                q.setParameter("empId", account.getEmpId());
            }
			if(StrUtil.isNotEmpty(account.getAccountName())){
				q.setParameter("accountName", account.getAccountName());
			}
			if(account.getStartTime()!= null){
				q.setParameter("startTime", account.getStartTime());
			}
			if(account.getEndTime()!= null){
				q.setParameter("endTime", DateUtil.getDateAdd(account.getEndTime(),1));
			}
			if(StrUtil.isNotEmpty(account.getState())){
				q.setParameter("state", account.getState());
			}
			if(ListUtil.isNotEmpty(account.getAccountRoles())){
			    q.setParameter("roleId", account.getAccountRoles().get(0).getRole().getRoleId());
			}
			if( super.hasPagination(startPosition, pageSize)){
				q.setFirstResult(startPosition);
				q.setMaxResults(pageSize);
			}
			return q.getResultList();
		}
		Query q = super.entityManager2.createQuery(jpql.toString());
		if( super.hasPagination(startPosition, pageSize)){
			q.setFirstResult(startPosition);
			q.setMaxResults(pageSize);
		}
		return q.getResultList();
	}
	
	@Override
    public List<SecurityAccount> findSecurityAccountListByQueryConditions(SecurityQueryConditions conditions) {
        return findSecurityAccountListByQueryConditions(PlatformConstant.ALL_POS,PlatformConstant.ALL_POS,conditions);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<SecurityAccount> findSecurityAccountListByQueryConditions(int startPosition,int pageSize, SecurityQueryConditions conditions) {
        StringBuffer jpql = new StringBuffer("select sa from SecurityAccount sa where (sa.deleted is null or sa.deleted !=1) ");
        if( conditions != null ){
            SecurityAccount account = conditions.getAccount();
            if(account != null ){
                if(StrUtil.isNotEmpty(account.getOrgId())){
                    jpql.append(" and sa.orgId = :orgId ");
                }
                if(StrUtil.isNotEmpty(account.getDeptId())){
                    jpql.append(" and sa.deptId = :deptId ");
                }
                if(StrUtil.isNotEmpty(account.getEmpId())){
                    jpql.append(" and sa.empId = :empId ");
                }
                if(StrUtil.isNotEmpty(account.getAccountName())){
                    jpql.append(" and locate(lower(:accountName),lower(sa.accountName) )>0 ");
                }
                if(account.getStartTime()!= null){
                    jpql.append(" and sa.startTime >= :startTime ");
                }
                if(account.getEndTime()!= null){
                    jpql.append(" and sa.endTime <= :endTime ");
                }
                if(StrUtil.isNotEmpty(account.getState())){
                    jpql.append(" and sa.state = :state ");
                }
            }
            
            if(conditions.getRole()!= null && StrUtil.isNotEmpty(conditions.getRole().getRoleId())){
                jpql.append(" and exists( ").append(
                            "  select asr.accountRoleId from SecurityAccountRole asr where asr.account.accountId = sa.accountId "
                ).append("     and asr.role.roleId =:roleId ")
                .append(" )");
            }
            Query q = super.entityManager2.createQuery(jpql.toString());
            if(account!=null){
                if(StrUtil.isNotEmpty(account.getOrgId())){
                    q.setParameter("orgId", account.getOrgId());
                }
                if(StrUtil.isNotEmpty(account.getDeptId())){
                    q.setParameter("deptId", account.getDeptId());
                }
                if(StrUtil.isNotEmpty(account.getEmpId())){
                    q.setParameter("empId", account.getEmpId());
                }
                if(StrUtil.isNotEmpty(account.getAccountName())){
                    q.setParameter("accountName", account.getAccountName());
                }
                if(account.getStartTime()!= null){
                    q.setParameter("startTime", account.getStartTime());
                }
                if(account.getEndTime()!= null){
                    q.setParameter("endTime", DateUtil.getDateAdd(account.getEndTime(),1));
                }
                if(StrUtil.isNotEmpty(account.getState())){
                    q.setParameter("state", account.getState());
                }
            }
            if(conditions.getRole()!= null && StrUtil.isNotEmpty(conditions.getRole().getRoleId())){
                q.setParameter("roleId", conditions.getRole().getRoleId());
            }
            if( super.hasPagination(startPosition, pageSize)){
                q.setFirstResult(startPosition);
                q.setMaxResults(pageSize);
            }
            return q.getResultList();
        }
        Query q = super.entityManager2.createQuery(jpql.toString());
        if( super.hasPagination(startPosition, pageSize)){
            q.setFirstResult(startPosition);
            q.setMaxResults(pageSize);
        }
        return q.getResultList();
    }

	@Override
	public void enableOrUnableSecurityAccount(List<String> list,String flag) {
		StringBuffer jpqlBuffer = new StringBuffer("update SecurityAccount sa set sa.state = :flag where 1=1 ");
		jpqlBuffer = JPAUtil.getConcatQLByParamKeyAndParamValuesAndSeparatorWithOrConditions(jpqlBuffer, "sa.accountId", list, "");
		super.entityManager2.createQuery(jpqlBuffer.toString()).setParameter("flag", flag).executeUpdate();
		super.flushClear(entityManager2);
	}
	
	@SuppressWarnings("unchecked")
    @Override
	public SecurityAccount validateAccountLawful(SecurityAccount account){
	    String jpql = " select account from SecurityAccount account " +
                      "where (account.deleted is null or account.deleted !=1) and account.accountName =:accountName and account.password = :password " +
                      "and account.state = :state " +
                      "and account.startTime <= :nowTime and account.endTime >= :nowTime " +
                      "and account.pwdValidStartDate <= :nowTime and account.pwdValidEndDate >= :nowTime ";
	    
        Query q = super.entityManager2.createQuery(jpql);
        q.setParameter("accountName",account.getAccountName());
        q.setParameter("password", account.getPassword());
        q.setParameter("state", "0");
        q.setParameter("nowTime", new Date());
        
        List<SecurityAccount> accountList = q.getResultList();
        if( ListUtil.isNotEmpty(accountList) ){
            return accountList.get(0);
        }else{
            return null;
        }
	}
	
	@SuppressWarnings("unchecked")
    @Override
    public SecurityAccount findSecurityAccountByAccountNameAndPWD(SecurityAccount account){
        String jpql = " select account from SecurityAccount account " +
                      "where (account.deleted is null or account.deleted !=1) and account.accountName =:accountName and account.password = :password ";        
        Query q = super.entityManager2.createQuery(jpql);
        q.setParameter("accountName",account.getAccountName());
        q.setParameter("password", account.getPassword());
        List<SecurityAccount> accountList = q.getResultList();
        if( ListUtil.isNotEmpty(accountList) ){
            return accountList.get(0);
        }else{
            return null;
        }
    }
	
	@SuppressWarnings("unchecked")
    @Override
    public SecurityAccount findSecurityAccountByAccountName(SecurityAccount account){
        String jpql = " select account from SecurityAccount account " +
                      "where (account.deleted is null or account.deleted !=1) and account.accountName =:accountName ";        
        Query q = super.entityManager2.createQuery(jpql);
        q.setParameter("accountName",account.getAccountName());
        List<SecurityAccount> accountList = q.getResultList();
        if( ListUtil.isNotEmpty(accountList) ){
            return accountList.get(0);
        }else{
            return null;
        }
    }
}
